<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    
    <title>Java NIO 笔记02 | Huhailong</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    
        <meta property="algolia:search" data-application-id="Z2O8U9ACCM" data-api-key="e2ecf104500495239b45a6d38163c2e8" data-index-name="huhailong">
    

    

    

    
        <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>😃</text></svg>">
    

    
    <link rel="stylesheet" href="https://unpkg.com/gitalk/dist/gitalk.css">
    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1630473019367.css">

    <script src="https://use.fontawesome.com/0807d6e1ca.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            gitalk: {
                enable: true,
                clientID: "de841f92787224d0163e",
                clientSecret: "2b8243d84acb67269b200a14fa12ed5d5a33c5b4",
                repo: "blog-message",
                owner: "huhailonggit",
                admin: ["huhailonggit",],
                distractionFreeMode: true  // Facebook-like distraction free mode
            },
            
            
            
        }
        window.aomori_logo_typed_animated = true
        window.aomori_search_algolia = true

    </script>

<meta name="generator" content="Hexo 5.4.0"></head>

<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-avatar avatar avatar-sm">
                <img src="/images/avatar.jpg" alt="胡海龙">
            </div>
            
            <div class="header-type-inner">
                
                    <div id="typed-strings" style="display:none">
                        <p>Huhailong</p>
                    </div>
                    <a class="header-type-title" id="typed" href="/"></a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
                <a href="/">Home</a>
                
                <a href="/archives">Archives</a>
                
                <a href="/friends">Links</a>
                
                <a href="/photography">Photography</a>
                
            </div>
            <div class="header-menu-social">
                
    <a class="social" target="_blank" href="https://gitee.com/hlovez">
        <box-icon type='' name='code-alt'></box-icon>
    </a>

    <a class="social" target="_blank" href="https://www.huhailong.vip">
        <box-icon type='' name='home'></box-icon>
    </a>

            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                    <a href="/">Home</a>
                    
                    <a href="/archives">Archives</a>
                    
                    <a href="/friends">Links</a>
                    
                    <a href="/photography">Photography</a>
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckulb6fpo0000woukcpxd1p6x" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      Java NIO 笔记02
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2021-10-10T14:14:43.529Z" itemprop="datePublished">2021-10-10</time>
</div>

            

            
            <div class="article-tag">
                <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java-NIO/" rel="tag">Java NIO</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E7%AC%94%E8%AE%B0/" rel="tag">笔记</a></li></ul>
            </div>
            
        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <h3 id="Java-NIO-笔记02"><a href="#Java-NIO-笔记02" class="headerlink" title="Java NIO 笔记02"></a>Java NIO 笔记02</h3><h4 id="Java-NIO-Buffer"><a href="#Java-NIO-Buffer" class="headerlink" title="Java NIO Buffer"></a>Java NIO Buffer</h4><p>Java NIO Buffer 在与Channel交互时被使用——channel从buffer中读取数据，channel将数据写入buffer。</p>
<p>一个buffer本质上是一块内存区域，我们可以在其中写入数据，之后可以再次读取数据。这个内存块被包裹在NIO 的 Buffer对象中。它提供了一些方法可以轻松的使用内存块。</p>
<h5 id="Buffer的基本使用"><a href="#Buffer的基本使用" class="headerlink" title="Buffer的基本使用"></a>Buffer的基本使用</h5><p>使用Buffer进行读取和写入一般有如下4个步骤：</p>
<ol>
<li>将数据写入Buffer</li>
<li>调用buffer.flip()方法</li>
<li>从缓冲区读取数据集</li>
<li>调用buffer.clear()或者buffer.compact()方法</li>
</ol>
<span id="more"></span>

<p>当你把数据写入buffer时，buffer会记录写了多少数据。一旦你需要读取数据，我们需要调用flip()方法将buffer从写入模式切换为读取模式。在读取模式下，缓冲区允许读取写入缓冲区的所有数据。</p>
<p>读取完数据后，需要清楚缓冲区，使其准备好再次写入。实现它有俩种方法——调用clear()方法或者compact()方法。其中clear()方法会清除整个buffer。compact()方法只清除已经读过的数据。任何未读数据都将移动到buffer的开头，数据将在未读数据之后写入缓冲区。</p>
<pre><code class="java">RandomAccessFile aFile = new RandomAccessFile(&quot;data/nio-data.txt&quot;,&quot;rw&quot;);
FileChannel inChannel = new FileChannel();
//创建容量为48字节的缓冲区
ByteBuffer buf = ByteBuffer.allocate(48);
//读入缓冲区
int bytesRead = inChannel.read(buf);
while(bytesRead != -1)&#123;
    buf.flip();    //make buffer ready for read (使缓冲区准备读取)
    while(buf.hasRemaining())&#123;
        System.out.print((char) buf.get()); //一次读取一个字节
    &#125;
    buf.clear();    //make buffer ready for writing (使缓冲区准备好写入)
    bytesRead = inChannel.read(buf);
&#125;
aFile.close();
</code></pre>
<h5 id="Buffer-的容量（capacity）、位置（position）和限制（limit）"><a href="#Buffer-的容量（capacity）、位置（position）和限制（limit）" class="headerlink" title="Buffer 的容量（capacity）、位置（position）和限制（limit）"></a>Buffer 的容量（capacity）、位置（position）和限制（limit）</h5><p>为了理解缓冲区是如何工作的有三个我们需要熟悉的属性，它们是：</p>
<ul>
<li>capacity （容量）</li>
<li>position （位置）</li>
<li>limit （限度）</li>
</ul>
<p>position和limit的含义取决于Buffer是处于读模式还是写模式，容量的含义和它处于何种模式无关。</p>
<p><img src="https://img-blog.csdnimg.cn/img_convert/6e4e44e2a0920b3b57fbfe244b0302bf.png" alt="Buffer2"></p>
<h6 id="capacity"><a href="#capacity" class="headerlink" title="capacity"></a>capacity</h6><p>作为一个内存块，Buffer有固定的大小，也成为容量（capacity）。一旦Buffer已满，这时，需要我们清空它，然后才能继续将更多的数据写入其中。</p>
<h6 id="position"><a href="#position" class="headerlink" title="position"></a>position</h6><p>当我们是处于写入模式时，即将数写入Buffer中时，position表示正在写入的位置，它最初时为0。当我们写入数据时，position将前进指向下一个单元格将数据插入。position的最大限度是(capacity - 1)</p>
<p>当我们是处于读取模式时，即读取数据从Buffer时，position表示正在读取的位置，当通过flip将模式由写入模式翻转到读取模式时，position将重置为0，读取数据是是从当前position读取数据并且position前进到下一个位置。</p>
<h6 id="limit"><a href="#limit" class="headerlink" title="limit"></a>limit</h6><p>在写入模式下，limit表示我们可以写入多少数据到buffer中，所以在写入模式下它与容量（capacity）是相等的。</p>
<p>在读取模式下，limit表示我们可以从数据中读取多少数据的限制，因此在读取模式下limit设置为写入模式的position，也就是读取与写入与一样多的数据。</p>
<h5 id="分配Buffer"><a href="#分配Buffer" class="headerlink" title="分配Buffer"></a>分配Buffer</h5><p>要想获得一个Buffer首先必须分配它，每一个Buffer类中的allocate()方法就是来做这件事情的，下面是示例：</p>
<pre><code class="java">ByteBuffer buf = ByteBuffer.allocate(48);    //分配一个48字节的ByteBuffer缓冲区
CharBuffer cuf = CharBuffer.allocate(1024);    //分配一个1024个字符空间的CharBuffer缓冲区
</code></pre>
<h5 id="写入数据到Buffer"><a href="#写入数据到Buffer" class="headerlink" title="写入数据到Buffer"></a>写入数据到Buffer</h5><p>将数据写入Buffer有俩种方法：</p>
<ul>
<li>将数据从通道写入Buffer区</li>
<li>通过Buffer的put()方法自己将数据写入缓冲区</li>
</ul>
<pre><code class="java">int bytesRead = inChannel.read(buf);    //read into buffer;
buf.put(127);
</code></pre>
<h5 id="flip"><a href="#flip" class="headerlink" title="flip()"></a>flip()</h5><p>flip()方法将Buffer从写入模式转为读取模式，调用flip()方法会将position重新设置为0，并将limit设置为刚刚写入模式时的position位置。</p>
<h5 id="从Buffer读取数据"><a href="#从Buffer读取数据" class="headerlink" title="从Buffer读取数据"></a>从Buffer读取数据</h5><p>从Buffer读取数据也有俩总方法：</p>
<ul>
<li>将Buffer中的数据读取到Channel中</li>
<li>使用Buffer自带的get()方法读取数据。</li>
</ul>
<pre><code class="java">//read from buffer into channel
int bytesRead = inChannel.write(buf);
byte aByte = buf.get();
</code></pre>
<h5 id="rewind"><a href="#rewind" class="headerlink" title="rewind()"></a>rewind()</h5><p>Buffer中rewind()方法可以将position重新设置为0，因此我们可以重新读取缓冲区中的所有数据。limit不会发生改变，因此也可以获取缓冲区中数据的数量。</p>
<h5 id="clear-和compact"><a href="#clear-和compact" class="headerlink" title="clear()和compact()"></a>clear()和compact()</h5><p>当从Buffer中读取完完数据后必须将Buffer再次准备为可写模式，这里可是使用clear()方法和compact()方法，clear()会清空这个buffer的数据，此时position为0，limit为buffer的capacity。compact()方法只会清除已读取的数据，compact()方法将所有未读的数据移动到开头，此时position会设置为未读数据的最后一个元素之后，limit和使用clear()方法一样，还是capacity。这样我们就可以再次写入数据而不会覆未读取的数据。</p>
<h5 id="mark-和-reset"><a href="#mark-和-reset" class="headerlink" title="mark() 和 reset()"></a>mark() 和 reset()</h5><p>我们可以通过Buffer中的mark()方法来标记给定的position，然后可以通过reset()方法重置回给定标记的位置，例如：</p>
<pre><code class="java">buffer.mark();
//调用几次get()方法
buffer.reset();    //重新设置position到mark的位置
</code></pre>
<h5 id="equals-and-compareTo"><a href="#equals-and-compareTo" class="headerlink" title="equals() and compareTo()"></a>equals() and compareTo()</h5><p>可以使用equals和compareTo()比较俩个buffer。</p>
<h6 id="equals"><a href="#equals" class="headerlink" title="equals()"></a>equals()</h6><p>如果满足有以下条件则俩个buffer是相等的：</p>
<ul>
<li>它们属于同一种类型（byte、char、int等）</li>
<li>它们在缓冲区中具有相同的剩余字节或字符等。</li>
<li>所有剩余的字节、字符等都是相等的。</li>
</ul>
<p>如上所述，equals只比较缓冲区的一部分，而不是其中的每个元素。实际上，它只是比较Buffer中的剩余元素。</p>
<h6 id="compareTo"><a href="#compareTo" class="headerlink" title="compareTo()"></a>compareTo()</h6><p>compareTo()方法比较俩个缓冲区的剩余元素（字符、字节等）。例如用于排序的程序中，在以下情况时，缓冲区被认为比另一个缓冲区小：</p>
<ul>
<li>与另一个缓冲区中的相应元素相等的第一个元素小于另一个缓冲区中的元素。</li>
<li>所有元素都是相等的，但第一个缓冲区在第二个缓冲区之前用完元素（它有更少的元素）。</li>
</ul>

        </div>

    </div>

    

    

    

    
<div class="article-copyright hairline">
  <p>
    本作品采用 <a rel="license noopener" target="_blank" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议</a> 进行许可。
  </p>
</div>


    

    
<nav class="article-nav">
  
    <a href="/2021/10/12/%E6%88%91%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%8F%90%E9%80%9F%E5%95%A6/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          我的服务器提速啦！
        
      </div>
    </a>
  
  
    <a href="/2021/10/07/Java%20NIO1/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">Java NIO 笔记01</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <!--<a class="share-item" target="_blank"
            href="https://twitter.com/share?text=Java NIO 笔记02 - Huhailong&url=https://hlovez.gitee.io/2021/10/10/Java%20NIO2/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>-->
        <a class="share-item" target="_blank"
            href="https://www.douban.com/share/service?name=Java NIO 笔记02 - Huhailong&url=https://hlovez.gitee.io/2021/10/10/Java%20NIO2/">
            <div class='fa fa-link' type='logo' ></div>
        </a>
        <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=Java NIO 笔记02 - Huhailong&url=https://hlovez.gitee.io/2021/10/10/Java%20NIO2/&pic=">
            <div class="fa fa-weibo"></i></div>
        </a>
    </section>

</article>






<section class="comments">
    <div id="gitalk-container"></div>
</section>





</div>
                </section>
            </section>

            
            <aside class="sidebar sidebar-search-fix">
                

    <div class="search">
    <div class="has-icon-right">
        <input type="text" class="form-input" id="search" placeholder="SEARCH" autocomplete="off">
        <div class="form-icon">
            <box-icon name='search' color="#3c4859"></box-icon>
        </div>
    </div>
    <div class="search-result" id="search-ps"></div>
</div>


<div class="widget" id="widget">
    
      
  <div class="widget-wrap">
    <div class="widget-inner">
      <div class="toc post-toc-html"></div>
    </div>
  </div>

    
      

    
      
  <div class="widget-wrap widget-tags">
    <div class="widget-title"><span>Tags</span></div>
    <div class="widget-inner">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Java-NIO/" rel="tag">Java NIO</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/java-NIO/" rel="tag">java NIO</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/redis/" rel="tag">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/shiro/" rel="tag">shiro</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/springboot/" rel="tag">springboot</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%AE%89%E5%85%A8/" rel="tag">安全</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%B6%88%E6%81%AF/" rel="tag">消息</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%AC%94%E8%AE%B0/" rel="tag">笔记</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E9%9A%8F%E7%AC%94/" rel="tag">随笔</a></li></ul>
    </div>
  </div>


    
      
  <div class="widget-wrap widget-recent-posts">
    <div class="widget-title"><span>Recent Posts</span></div>
    <div class="widget-inner">
      <ul>
        
          <li>
            <a href="/2021/10/30/Java%20NIO-5/">Java NIO 笔记05</a>
          </li>
        
          <li>
            <a href="/2021/10/25/Java%20NIO-4/">Java NIO 笔记04</a>
          </li>
        
          <li>
            <a href="/2021/10/17/Java%20NIO-3/">Java NIO 笔记03</a>
          </li>
        
          <li>
            <a href="/2021/10/12/%E6%88%91%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%8F%90%E9%80%9F%E5%95%A6/">我的服务器提速啦！</a>
          </li>
        
          <li>
            <a href="/2021/10/10/Java%20NIO2/">Java NIO 笔记02</a>
          </li>
        
      </ul>
    </div>
  </div>

    
      
  <div class="widget-wrap widget-archive">
    <div class="widget-title"><span>Archive</span></div>
    <div class="widget-inner">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/">2021</a></li></ul>
    </div>
  </div>


    
</div>

<div id="backtop"><i class="icon icon-arrow-up"></i></div>
            </aside>
            
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            Huhailong &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori </a>
            
            🧡 <span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次
</span><span id="busuanzi_container_site_uv">本站访客数<span id="busuanzi_value_site_uv"></span>人次</span>
            
        </div>
    </div>

</footer>


<script src="https://unpkg.com/gitalk/dist/gitalk.min.js"></script>





<script src="/dist/build.js?1630473019367.js"></script>


<script src="/dist/custom.js?1630473019367.js"></script>



<!-- 百度链接提交 -->
<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        }
        else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>




    <script src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>


<!-- Baidu Analytics-->
<script type="text/javascript">
    var _hmt = _hmt || [];
    (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?c15cbbf786572a8cb10802fa47753bb5";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })();
</script>



</body>

</html>